
import json
import logging
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.contrib.auth.models import AnonymousUser
from order_app.models import Order
from user_app.models import User

logger = logging.getLogger(__name__)


class LocationConsumer(AsyncWebsocketConsumer):
    """位置跟踪WebSocket消费者"""
    
    async def connect(self):
        """处理WebSocket连接"""
        self.order_id = self.scope['url_route']['kwargs']['order_id']
        self.user = self.scope['user']
        
        # 验证用户和订单
        if isinstance(self.user, AnonymousUser):
            await self.close()
            return
        
        # 检查用户是否有权限访问该订单的位置信息
        has_permission = await self._check_permission()
        if not has_permission:
            await self.close()
            return
        
        # 加入订单特定的组
        self.group_name = f'order_{self.order_id}_tracking'
        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )
        
        await self.accept()
        logger.info(f"WebSocket connected: {self.user.phone} joined {self.group_name}")
    
    async def disconnect(self, close_code):
        """处理WebSocket断开连接"""
        if hasattr(self, 'group_name'):
            await self.channel_layer.group_discard(
                self.group_name,
                self.channel_name
            )
            logger.info(f"WebSocket disconnected: {self.user.phone} left {self.group_name}")
    
    async def receive(self, text_data):
        """接收WebSocket消息"""
        try:
            data = json.loads(text_data)
            message_type = data.get('type')
            
            if message_type == 'ping':
                # 处理心跳消息
                await self.send(text_data=json.dumps({
                    'type': 'pong',
                    'message': 'pong'
                }))
            elif message_type == 'location_update':
                # 处理位置更新消息
                await self._handle_location_update(data)
        except json.JSONDecodeError:
            logger.error("Invalid JSON data received")
        except Exception as e:
            logger.error(f"Error processing WebSocket message: {str(e)}")
    
    async def location_update(self, event):
        """处理位置更新事件"""
        await self.send(text_data=json.dumps(event))
    
    async def _handle_location_update(self, data):
        """处理位置更新"""
        # 这里可以添加位置更新处理逻辑
        # 例如保存到数据库或转发给其他用户
        
        # 转发给组内的所有用户
        await self.channel_layer.group_send(
            self.group_name,
            {
                'type': 'location_update',
                'data': data
            }
        )
    
    @database_sync_to_async
    def _check_permission(self):
        """检查用户是否有权限访问订单的位置信息"""
        try:
            order = Order.objects.get(id=self.order_id)
            return self.user == order.shipper or self.user == order.driver
        except Order.DoesNotExist:
            return False